#pragma once

#include <iostream>
#include <functional>

#include "socket.hpp"
#include "Inetaddr.hpp"
#include "log.hpp"
#include "protocol.hpp"

using namespace socket_namespace;
using namespace log_namespace;

using process_t = std::function<std::shared_ptr<Response>(std::shared_ptr<Request> )>;

class IOService
{
public:
    IOService(process_t process)
        :_process(process)
    {
    }

    void IOexecute(socketPtr socket, inetAddr addr)
    {
        std::string packagestreamQueue;
        while (true)
        {
            // 1. 负荷读取
            ssize_t n = socket->Recv(&packagestreamQueue);
            if (n <= 0)
            {
                LOG(INFO, "client %s quit or recv error\n", addr.addrStr().c_str());
                break;
            }

            std::cout << "----------------------------------------" << std::endl;
            std::cout << "packagestreamQueue: \n" << packagestreamQueue << std::endl;

            // 2. 报文解析
            std::string package = Decode(packagestreamQueue);
            if (package.empty())
            {
                continue;
            }
            // 走到这一行，package一定是一个完整的报文
            auto req = Factory::buildRequest();
            std::cout << "package: \n" << package << std::endl;

            // 3. 反序列化
            req->Deserialize(package);

            // 4. 业务处理
            auto resp = _process(req); // 通过请求，得到应答

            // 5. 构建序列化应答
            std::string respjson;
            resp->Serialize(&respjson);
            std::cout << "respjson: \n" << respjson << std::endl;

            // 6. 添加len长度报头
            respjson = Encode(respjson);
            std::cout << "respjson add header done: \n" << respjson << std::endl;

            // 7. 将报文发送回去
            socket->Send(respjson);
        }
    }

    ~IOService()
    {
    }

private:
    process_t _process;
};
